using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace EntityKit.Runtime
{
    /// <summary>
    /// Unity随机数助手类，提供各种常用的随机功能
    /// </summary>
    public static class RandomHelper
    {
        #region 基础随机数生成

        /// <summary>
        /// 获取指定范围内的随机整数 [min, max)
        /// </summary>
        /// <param name="min">最小值（包含）</param>
        /// <param name="max">最大值（不包含）</param>
        /// <returns>随机整数</returns>
        public static int Range(int min, int max)
        {
            return UnityEngine.Random.Range(min, max);
        }

        /// <summary>
        /// 获取指定范围内的随机浮点数 [min, max)
        /// </summary>
        /// <param name="min">最小值（包含）</param>
        /// <param name="max">最大值（不包含）</param>
        /// <returns>随机浮点数</returns>
        public static float Range(float min, float max)
        {
            return UnityEngine.Random.Range(min, max);
        }

        /// <summary>
        /// 获取0到1之间的随机浮点数
        /// </summary>
        /// <returns>0到1之间的随机浮点数</returns>
        public static float Value()
        {
            return UnityEngine.Random.value;
        }

        /// <summary>
        /// 获取随机角度（0到360度）
        /// </summary>
        /// <returns>随机角度</returns>
        public static float Rotation()
        {
            return UnityEngine.Random.rotationUniform.eulerAngles.z;
        }

        /// <summary>
        /// 获取随机旋转
        /// </summary>
        /// <returns>随机四元数</returns>
        public static Quaternion RotationUniform()
        {
            return UnityEngine.Random.rotationUniform;
        }

        /// <summary>
        /// 获取随机旋转（围绕Y轴）
        /// </summary>
        /// <returns>随机Y轴旋转</returns>
        public static Quaternion RotationY()
        {
            return Quaternion.Euler(0, Range(0, 360), 0);
        }

        /// <summary>
        /// 获取随机布尔值
        /// </summary>
        /// <returns>随机布尔值</returns>
        public static bool Bool()
        {
            return UnityEngine.Random.value > 0.5f;
        }

        /// <summary>
        /// 根据指定概率判断是否成功
        /// 例如：Chance(0.3f) 表示有30%的概率返回true，70%的概率返回false
        /// </summary>
        /// <param name="probability">成功概率（0-1之间）</param>
        /// <returns>是否成功</returns>
        public static bool Chance(float probability)
        {
            return UnityEngine.Random.value < probability;
        }

        #endregion

        #region 随机颜色

        /// <summary>
        /// 获取随机颜色
        /// </summary>
        /// <returns>随机颜色</returns>
        public static Color Color()
        {
            return new Color(Value(), Value(), Value());
        }

        /// <summary>
        /// 获取随机RGB颜色（不包括alpha通道）
        /// </summary>
        /// <returns>随机RGB颜色</returns>
        public static Color ColorRGB()
        {
            return new Color(Value(), Value(), Value(), 1.0f);
        }

        /// <summary>
        /// 获取随机灰度颜色
        /// </summary>
        /// <returns>随机灰度颜色</returns>
        public static Color ColorGrayscale()
        {
            float value = Value();
            return new Color(value, value, value);
        }

        /// <summary>
        /// 获取随机HSL颜色
        /// </summary>
        /// <param name="hue">色相范围（0-1，默认0-1）</param>
        /// <param name="saturation">饱和度范围（0-1，默认0-1）</param>
        /// <param name="lightness">亮度范围（0-1，默认0-1）</param>
        /// <returns>随机HSL颜色</returns>
        public static Color ColorHSL(Vector2? hue = null, Vector2? saturation = null, Vector2? lightness = null)
        {
            Vector2 hRange = hue ?? new Vector2(0, 1);
            Vector2 sRange = saturation ?? new Vector2(0, 1);
            Vector2 lRange = lightness ?? new Vector2(0, 1);

            float h = Range(hRange.x, hRange.y);
            float s = Range(sRange.x, sRange.y);
            float l = Range(lRange.x, lRange.y);

            return HSLToRGB(h, s, l);
        }

        /// <summary>
        /// HSL转RGB颜色
        /// </summary>
        /// <param name="h">色相</param>
        /// <param name="s">饱和度</param>
        /// <param name="l">亮度</param>
        /// <returns>RGB颜色</returns>
        private static Color HSLToRGB(float h, float s, float l)
        {
            float r, g, b;

            if (s == 0)
            {
                r = g = b = l;
            }
            else
            {
                float hue2rgb(float p, float q, float t)
                {
                    if (t < 0) t += 1;
                    if (t > 1) t -= 1;
                    if (t < 1f / 6) return p + (q - p) * 6 * t;
                    if (t < 1f / 2) return q;
                    if (t < 2f / 3) return p + (q - p) * (2f / 3 - t) * 6;
                    return p;
                }

                float q = l < 0.5f ? l * (1 + s) : l + s - l * s;
                float p = 2 * l - q;
                r = hue2rgb(p, q, h + 1f / 3);
                g = hue2rgb(p, q, h);
                b = hue2rgb(p, q, h - 1f / 3);
            }

            return new Color(r, g, b);
        }

        #endregion

        #region 随机向量

        /// <summary>
        /// 获取随机二维点（在单位圆内）
        /// </summary>
        /// <returns>随机二维点</returns>
        public static Vector2 InsideUnitCircle()
        {
            return UnityEngine.Random.insideUnitCircle;
        }

        /// <summary>
        /// 获取随机三维点（在单位球内）
        /// </summary>
        /// <returns>随机三维点</returns>
        public static Vector3 InsideUnitSphere()
        {
            return UnityEngine.Random.insideUnitSphere;
        }

        /// <summary>
        /// 获取随机三维点（在单位球表面上）
        /// </summary>
        /// <returns>单位球表面上的随机点</returns>
        public static Vector3 OnUnitSphere()
        {
            return UnityEngine.Random.onUnitSphere;
        }

        /// <summary>
        /// 获取随机二维点（在矩形范围内）
        /// </summary>
        /// <param name="min">最小坐标</param>
        /// <param name="max">最大坐标</param>
        /// <returns>矩形范围内的随机点</returns>
        public static Vector2 InsideRect(Vector2 min, Vector2 max)
        {
            return new Vector2(Range(min.x, max.x), Range(min.y, max.y));
        }

        /// <summary>
        /// 获取随机三维点（在立方体内）
        /// </summary>
        /// <param name="min">最小坐标</param>
        /// <param name="max">最大坐标</param>
        /// <returns>立方体内的随机点</returns>
        public static Vector3 InsideCube(Vector3 min, Vector3 max)
        {
            return new Vector3(Range(min.x, max.x), Range(min.y, max.y), Range(min.z, max.z));
        }

        /// <summary>
        /// 获取随机方向（二维单位向量）
        /// </summary>
        /// <returns>随机方向</returns>
        public static Vector2 RandomDirection2D()
        {
            float angle = Range(0, 2 * Mathf.PI);
            return new Vector2(Mathf.Cos(angle), Mathf.Sin(angle));
        }

        /// <summary>
        /// 获取随机方向（三维单位向量）
        /// </summary>
        /// <returns>随机方向</returns>
        public static Vector3 RandomDirection3D()
        {
            return UnityEngine.Random.onUnitSphere;
        }

        #endregion

        #region 随机字符串

        /// <summary>
        /// 生成随机字符串
        /// </summary>
        /// <param name="length">字符串长度</param>
        /// <param name="chars">字符集</param>
        /// <returns>随机字符串</returns>
        public static string String(int length, string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
        {
            if (length <= 0)
                return string.Empty;

            char[] result = new char[length];
            for (int i = 0; i < length; i++)
            {
                result[i] = chars[Range(0, chars.Length)];
            }

            return new string(result);
        }

        /// <summary>
        /// 生成随机字母字符串
        /// </summary>
        /// <param name="length">字符串长度</param>
        /// <returns>随机字母字符串</returns>
        public static string AlphaString(int length)
        {
            return String(length, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
        }

        /// <summary>
        /// 生成随机数字字符串
        /// </summary>
        /// <param name="length">字符串长度</param>
        /// <returns>随机数字字符串</returns>
        public static string NumericString(int length)
        {
            return String(length, "0123456789");
        }

        #endregion

        #region 随机分布

        /// <summary>
        /// 获取正态分布（高斯分布）随机数
        /// </summary>
        /// <param name="mean">均值</param>
        /// <param name="stdDev">标准差</param>
        /// <returns>正态分布随机数</returns>
        public static float Normal(float mean = 0f, float stdDev = 1f)
        {
            // 使用Box-Muller变换生成正态分布随机数
            float u1 = Value();
            float u2 = Value();

            while (u1 <= float.Epsilon)
                u1 = Value();

            float randStdNormal = Mathf.Sqrt(-2.0f * Mathf.Log(u1)) * Mathf.Sin(2.0f * Mathf.PI * u2);
            return mean + stdDev * randStdNormal;
        }

        /// <summary>
        /// 获取指数分布随机数
        /// </summary>
        /// <param name="lambda">lambda参数</param>
        /// <returns>指数分布随机数</returns>
        public static float Exponential(float lambda = 1f)
        {
            float u = Value();
            while (u <= float.Epsilon)
                u = Value();
            return -Mathf.Log(u) / lambda;
        }

        #endregion
    }
}